import 'dart:async';
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'index.dart';

/// ZVT协议异常类
class ZVTException implements Exception {
  final String message;
  final int? resultCode;
  final Map<String, dynamic>? details;

  ZVTException(this.message, {this.resultCode, this.details});

  @override
  String toString() =>
      'ZVTException: $message${resultCode != null ? ' (Code: $resultCode)' : ''}';
}

/// ZVT协议支付工具类（线程安全单例+全局唯一监听器+队列分发）
class ZVTPayment {
  // --- 单例实现 ---
  static final ZVTPayment _instance = ZVTPayment._internal();
  factory ZVTPayment() => _instance;
  ZVTPayment._internal();
  static ZVTPayment current() => _instance;

  String? ip;
  int port = 20008; // ZVT默认端口
  Socket? socket;
  bool _isConnected = false;

  // 全局唯一socket监听器
  StreamSubscription<List<int>>? _messageSubscription;
  // 命令队列
  final List<Completer<TransactionResponse>> _pendingCompletions = [];
  final List<Function(String)?> _pendingLoggers = [];
  final List<List<int>?> _pendingCompleteStatus = [];

  // 打印数据缓存
  List<List<int>> lastPrintMessages = [];

  // --- 连接与监听 ---
  void setConnectIP({required String ip, int? port}) {
    this.ip = ip;
    if (port != null) this.port = port;
  }

  Future<void> connect() async {
    if (_isConnected && socket != null) return;
    try {
      socket = await Socket.connect(ip, port, timeout: _connectionTimeout);
      _isConnected = true;
      _lastError = null;
      _setupMessageListener();
    } catch (e) {
      _lastError = '连接终端失败: $e';
      throw ZVTException('连接终端失败: $e');
    }
  }

  void _setupMessageListener() {
    _messageSubscription?.cancel();
    _messageSubscription = socket!.listen(
      _handleIncomingMessage,
      onError: (error) {
        _isConnected = false;
        _lastError = '通信错误: $error';
        // _completeAllPendingWithError(ZVTException('通信错误: $error'));
      },
      onDone: () {
        _isConnected = false;
        _lastError = '连接已关闭';
        // _completeAllPendingWithError(ZVTException('连接已关闭'));
      },
    );
  }

  void disconnect() {
    // _completeAllPendingWithError(ZVTException('连接已断开'));
    _messageSubscription?.cancel();
    _messageSubscription = null;
    socket?.close();
    socket = null;
    _isConnected = false;
  }

  // --- 命令发送与队列分发 ---
  Future<TransactionResponse> _sendMessage({
    required List<int> command,
    Function(String)? codeLog,
    List<int>? completeStatus,
  }) async {
    if (!_isConnected || socket == null) {
      await connect();
    }
    _totalTransactions++;
    try {
      socket!.add(command);
      codeLog?.call("ECR->PT: ${ZVTCommand.bytesToHex(command)}");
      Completer<TransactionResponse> completer = Completer();
      _pendingCompletions.add(completer);
      _pendingLoggers.add(codeLog);
      _pendingCompleteStatus.add(completeStatus);
      Timer(_operationTimeout, () {
        if (!completer.isCompleted) {
          _failedTransactions++;
          _lastError = '操作超时';
          _completeCurrentPendingWithError(completer, ZVTException('操作超时'));
        }
      });
      return await completer.future;
    } catch (e) {
      _failedTransactions++;
      if (e is ZVTException) {
        _lastError = e.message;
        rethrow;
      }
      _lastError = '发送消息失败: $e';
      throw ZVTException('发送消息失败: $e');
    }
  }

  void _handleIncomingMessage(List<int> event) {
    if (_pendingCompletions.isEmpty) return;
    final completer = _pendingCompletions.first;
    final logger = _pendingLoggers.first;
    final completeStatus = _pendingCompleteStatus.first;
    logger?.call("PT->ECR: ${ZVTCommand.bytesToHex(event)}");

    if (completeStatus != null && event.length >= completeStatus.length) {
      bool isComplete = true;
      for (int i = 0; i < completeStatus.length; i++) {
        if (event[i] != completeStatus[i]) {
          isComplete = false;
          break;
        }
      }
      if (isComplete) {
        logger?.call(
            '检测到完成状态: ${completeStatus.map((b) => b.toRadixString(16).padLeft(2, '0')).join(' ').toUpperCase()}');
        _lastTransactionTime = DateTime.now();
        _completeCurrentPending(
          completer,
          TransactionResponse(
            status: "success",
            message: "成功",
            timestamp: _lastTransactionTime!.toIso8601String(),
            finalAck: true,
            fields: {},
          ),
        );
        lastPrintMessages.clear();
      }
    }
    // ACK
    if (event[0] == ZVTCommand.RESP_ACK && event[1] == ZVTCommand.ACK_OK) {
      return;
    } else if (event.length >= 3 &&
        event[0] == ZVTCommand.FINAL_ACK_CMD &&
        event[1] == ZVTCommand.FINAL_ACK_SUB) {
      // 最终确认 (06 0F)
      _handleFinalAck(event, completer, logger);
      return;
    } else if (event[0] == ZVTCommand.RESP_STATUS) {
      // 状态信息
      _handleStatusMessage(event, completer, logger);
      return;
    } else if (event[0] == ZVTCommand.FINAL_ACK_CMD &&
        event[1] == ZVTCommand.RESP_PRINT) {
      // 打印数据
      _handlePrintMessage(event, completer, logger);
      return;
    } else if (event[1] == ZVTCommand.RESP_ERROR) {
      // 错误响应
      _handleErrorMessage(event, completer, logger);
      return;
    } else if (event[0] == 0x84 && event[1] == 0x83 || event[1] == 0xB5) {
      // 其它ACK都视为异常
      final msg = "ZVT ACK异常: ${ZVTCommand.bytesToHex(event)}";
      _completeCurrentPendingWithError(
        _pendingCompletions.first,
        ZVTException(msg, resultCode: event[1]),
      );
      return;
    }
  }

  void _handleStatusMessage(List<int> event,
      Completer<TransactionResponse> completer, Function(String)? logger) {
    socket!.add(ZVTCommand.FINAL_ACK_RESPONSE);
    logger?.call(
        "ECR->PT: ${ZVTCommand.bytesToHex(ZVTCommand.FINAL_ACK_RESPONSE)}");

    int? code;
    if (event.length > 3) code = event[3];
    if (code != null && ZVTCommand.isErrorStatusCode(code)) {
      _failedTransactions++;
      _lastError = ZVTCommand.getStatusCodeDescription(code);
      _completeCurrentPendingWithError(
        completer,
        ZVTException(_lastError!, resultCode: code),
      );
    }
    // 其他状态码继续等待最终确认
  }

  void _handlePrintMessage(List<int> event,
      Completer<TransactionResponse> completer, Function(String)? logger) {
    // 缓存打印数据
    lastPrintMessages.add(event);
    socket!.add(ZVTCommand.FINAL_ACK_RESPONSE);
    logger?.call(
        "ECR->PT: ${ZVTCommand.bytesToHex(ZVTCommand.FINAL_ACK_RESPONSE)}");
  }

  void _handleErrorMessage(List<int> event,
      Completer<TransactionResponse> completer, Function(String)? logger) {
    int errorCode = event.length > 3 ? event[3] : 0;
    String msg = ZVTCommand.getStatusCodeDescription(errorCode);
    _failedTransactions++;
    _lastError = msg;
    _completeCurrentPendingWithError(
      completer,
      ZVTException(msg, resultCode: errorCode),
    );
    socket!.add(ZVTCommand.FINAL_ACK_RESPONSE);
    logger?.call(
        "ECR->PT: ${ZVTCommand.bytesToHex(ZVTCommand.FINAL_ACK_RESPONSE)}");
  }

  void _handleFinalAck(List<int> event,
      Completer<TransactionResponse> completer, Function(String)? logger) {
    socket!.add(ZVTCommand.FINAL_ACK_RESPONSE);
    logger?.call(
        "ECR->PT: ${ZVTCommand.bytesToHex(ZVTCommand.FINAL_ACK_RESPONSE)}");

    String? fullText;
    if (lastPrintMessages.isNotEmpty) {
      final fields = _extractFieldsFromPrintMessages();
      if (fields.containsKey(0xFFFF)) {
        // 使用ISO-8859-2解码以正确处理捷克语等中欧语言的带音标字符
        fullText = _decodeIso8859_2(fields[0xFFFF]!);
        debugPrint('fullText--->$fullText');
      }
    }
    ReceiptModel? receipt;
    if (fullText != null) {
      // 只删除控制字符（0x00-0x1F，除了换行符和回车符），保留所有其他字符包括捷克语字符
      fullText = fullText.replaceAll(RegExp(r'[\x00-\x08\x0B\x0C\x0E-\x1F]'), '');
      receipt = ReceiptModel.fromFullText(fullText);
    } else {
      receipt = null;
    }
    _successfulTransactions++;
    _lastTransactionTime = DateTime.now();
    _completeCurrentPending(
        completer,
        TransactionResponse(
          status: "success",
          message: "成功",
          timestamp: _lastTransactionTime!.toIso8601String(),
          finalAck: true,
          fields: {},
          receipt: receipt,
        ));
    lastPrintMessages.clear();
  }

  Map<int, List<int>> _extractFieldsFromPrintMessages() {
    if (lastPrintMessages.isEmpty) return {};
    final Uint8List msg = Uint8List.fromList(lastPrintMessages.last);
    return _extractFieldsFromPrintMessageBytes(msg);
  }

  Map<int, List<int>> _extractFieldsFromPrintMessageBytes(Uint8List msg) {
    final result = <int, List<int>>{};
    int i = 0;

    // 检查是否为打印报文 (0x06 0xD3)
    if (msg.length > 2 && msg[0] == 0x06 && msg[1] == 0xD3) {
      // 跳过报文头和前面的非文本数据，直到第一个0x07
      int startIndex = -1;
      for (int j = 2; j < msg.length; j++) {
        if (msg[j] == 0x07) {
          startIndex = j;
          break;
        }
      }
      if (startIndex != -1) {
        // 从第一个0x07开始，将所有后续内容合并为一个大的文本块
        List<int> combinedTextBytes = [];
        i = startIndex;
        while (i < msg.length) {
          // 假设0x07是文本块的tag, 后面紧跟长度
          if (msg[i] == 0x07 && i + 1 < msg.length) {
            final len = msg[i + 1];
            if (i + 2 + len <= msg.length) {
              combinedTextBytes.addAll(msg.sublist(i + 2, i + 2 + len));
              // ZVT协议使用0x0d或0x0a作为换行
              combinedTextBytes.add(0x0A);
              i += 2 + len;
            } else {
              i++; // 避免死循环
            }
          } else {
            i++; // 跳过无法解析的字节
          }
        }
        // 将完整的文本块存入一个特殊的tag (e.g., 0xFFFF)
        result[0xFFFF] = combinedTextBytes;
        return result;
      }
    }
    // --- 如果不是打印报文，则回退到之前的TLV解析逻辑 ---
    final Set<int> controlCodes = {
      0x1B,
      0x0A,
      0x0D,
      0x1F,
      0x04,
      0x13,
      0x15,
      0x18,
      0x12,
      0x10,
      0x14,
      0x24,
      0x25,
      0x37,
      0x09,
      0x00,
    };
    while (i < msg.length && msg[i] < 0x06) {
      i++;
    }
    while (i < msg.length) {
      if (controlCodes.contains(msg[i])) {
        i++;
        continue;
      }
      if (msg[i] == 0x06 && i + 2 < msg.length) {
        final command = msg[i + 1];
        final len = msg[i + 2];
        if (i + 3 + len <= msg.length) {
          result[0x0600 + command] = msg.sublist(i + 3, i + 3 + len);
        }
        i += 3 + len;
        continue;
      }
      if (i + 1 >= msg.length) break;
      final tag = msg[i++];
      int len = msg[i++];
      if (len & 0x80 != 0) {
        final bytesCount = len & 0x7F;
        len = 0;
        for (var j = 0; j < bytesCount; j++) {
          if (i >= msg.length) break;
          len = (len << 8) | msg[i++];
        }
      }
      if (i + len > msg.length) {
        debugPrint(
            'Invalid TLV: tag=0x${tag.toRadixString(16).padLeft(2, '0')} len=$len at $i (msg length ${msg.length})');
        break;
      }
      if (tag == 0xD3) {
        final nested = _extractFieldsFromPrintMessageBytes(
            Uint8List.fromList(msg.sublist(i, i + len)));
        nested.forEach((key, value) {
          result[key] = value;
        });
      } else {
        result[tag] = msg.sublist(i, i + len);
      }
      i += len;
    }
    return result;
  }

  void _completeCurrentPending(
      Completer<TransactionResponse> completer, TransactionResponse result) {
    if (!completer.isCompleted) {
      completer.complete(result);
    }
    _removeCurrentPending();
  }

  void _completeCurrentPendingWithError(
      Completer<TransactionResponse> completer, ZVTException error) {
    if (!completer.isCompleted) {
      completer.completeError(error);
    }
    _removeCurrentPending();
  }

  void _removeCurrentPending() {
    if (_pendingCompletions.isNotEmpty) {
      _pendingCompletions.removeAt(0);
    }
    if (_pendingLoggers.isNotEmpty) {
      _pendingLoggers.removeAt(0);
    }
    if (_pendingCompleteStatus.isNotEmpty) {
      _pendingCompleteStatus.removeAt(0);
    }
  }

  // --- 业务方法和工具方法（保持原有接口）---
  // ...（此处省略，保留你原有的业务方法和静态工具方法）...

  // 私有成员变量
  Duration _connectionTimeout = const Duration(seconds: 20);
  Duration _operationTimeout = const Duration(seconds: 60);
  String? _lastError;
  int _totalTransactions = 0;
  int _successfulTransactions = 0;
  int _failedTransactions = 0;
  DateTime? _lastTransactionTime;
  Duration? _averageResponseTime;

  bool get isConnected => _isConnected && socket != null;
  String? get lastError => _lastError;
  void clearError() {
    _lastError = null;
  }

  /// 授权交易（销售交易）
  Future<TransactionResponse> authorization({
    required double amount,
    int? timeout,
    int? maxStatusInfos,
    int? currencyIsoCode,
    Function(String)? codeLog,
  }) async {
    if (timeout != null) {
      setOperationTimeout(Duration(seconds: timeout));
    }
    // 构建交易命令
    List<int> command = ZVTCommand.buildTransactionCommand(
      amount,
      currencyIsoCode: currencyIsoCode,
    );

    // 使用统一的_sendMessage方法，保持与其他方法的一致性
    return await _sendMessage(command: command, codeLog: codeLog);
  }

  /// 关闭批次（日终结算）
  Future<TransactionResponse> endOfDay({
    Function(String)? codeLog,
  }) async {
    List<int> command = ZVTCommand.buildEndOfDayCommand();
    return await _sendMessage(command: command, codeLog: codeLog);
  }

  /// 中止交易
  Future<TransactionResponse> abort({
    Function(String)? codeLog,
  }) async {
    List<int> command = ZVTCommand.buildAbortCommand();
    return await _sendMessage(command: command, codeLog: codeLog);
  }

  /// 冲正交易
  Future<TransactionResponse> reversal({
    required String batchNumber,
    Function(String)? codeLog,
  }) async {
    List<int> command = ZVTCommand.buildReversalCommand(
      batchNumber,
    );
    return await _sendMessage(command: command, codeLog: codeLog);
  }

  /// 退款交易（Refund 06 31）
  /// 根据ZVT协议文档第2.15节 "Refund (06 31)"
  ///
  /// [amount] 退款金额
  /// [timeout] 超时时间（秒）
  /// [codeLog] 日志回调函数
  Future<TransactionResponse> refund({
    required double amount,
    int? timeout,
    int? currencyIsoCode,
    Function(String)? codeLog,
  }) async {
    if (timeout != null) {
      setOperationTimeout(Duration(seconds: timeout));
    }
    // 构建退款命令
    List<int> command = ZVTCommand.buildRefundCommand(
      amount,
      currencyIsoCode: currencyIsoCode,
    );
    return await _sendMessage(command: command, codeLog: codeLog);
  }

  /// 注册配置
  /// [printPaymentReceipt] 通过支付终端进行支付功能的收据打印
  /// [printManagerReceipt] 通过支付终端进行管理功能的收据打印
  /// [sendStatusInfomation] 发送中间状态信息
  /// [allowStartPaymenttTerminal] 允许通过支付终端开始付款
  /// [allowAdminPaymentTerminal] 允许通过支付终端进行管理
  /// [currencyIsoCode] 货币代码
  Future<TransactionResponse> registration({
    bool printPaymentReceipt = false,
    bool printManagerReceipt = false,
    bool sendStatusInfomation = true,
    bool allowStartPaymenttTerminal = false,
    bool allowAdminPaymentTerminal = false,
    int currencyIsoCode = 978,
    Function(String)? codeLog,
  }) async {
    List<int> command = ZVTCommand.buildRegistrationCommand(
      printPaymentReceipt: printPaymentReceipt,
      printManagerReceipt: printManagerReceipt,
      sendStatusInfomation: sendStatusInfomation,
      allowStartPaymenttTerminal: allowStartPaymenttTerminal,
      allowAdminPaymentTerminal: allowAdminPaymentTerminal,
      currencyIsoCode: currencyIsoCode,
    );
    return await _sendMessage(command: command, codeLog: codeLog);
  }

  ///注销登记
  Future<TransactionResponse> logOff({
    Function(String)? codeLog,
    List<int> completeStatus = const [0x80, 0x00, 0x00],
  }) async {
    List<int> command = ZVTCommand.buildLogOff();
    return await _sendMessage(
      command: command,
      codeLog: codeLog,
      completeStatus: completeStatus,
    );
  }

  ///重新打印票据
  Future<TransactionResponse> repeatReceipt({Function(String)? codeLog}) async {
    List<int> command = ZVTCommand.buildRepeatReceipt();
    return await _sendMessage(
      command: command,
      codeLog: codeLog,
    );
  }

  /// 批量交易处理
  Future<List<TransactionResponse>> batchProcess({
    required List<TransactionParams> transactions,
    Function(int current, int total, TransactionResponse result)? onProgress,
  }) async {
    List<TransactionResponse> results = [];
    for (int i = 0; i < transactions.length; i++) {
      try {
        final param = transactions[i];
        final result = await authorization(
          amount: param.amount,
          timeout: param.timeout,
          maxStatusInfos: param.maxStatusInfos,
          codeLog: param.codeLog,
        );
        results.add(result);
        onProgress?.call(i + 1, transactions.length, result);
        if (i < transactions.length - 1) {
          await Future.delayed(const Duration(seconds: 2));
        }
      } catch (e) {
        results.add(TransactionResponse(
          status: "error",
          message: e.toString(),
          timestamp: DateTime.now().toIso8601String(),
          finalAck: false,
          fields: {},
          receipt: null,
        ));
        onProgress?.call(i + 1, transactions.length, results.last);
      }
    }
    return results;
  }

  /// 获取交易统计信息
  Map<String, dynamic> getTransactionStats() {
    return {
      'totalTransactions': _totalTransactions,
      'successfulTransactions': _successfulTransactions,
      'failedTransactions': _failedTransactions,
      'lastTransactionTime': _lastTransactionTime?.toIso8601String(),
      'averageResponseTime': _averageResponseTime?.inMilliseconds,
    };
  }

  /// 重置统计信息
  void resetStats() {
    _totalTransactions = 0;
    _successfulTransactions = 0;
    _failedTransactions = 0;
    _lastTransactionTime = null;
    _averageResponseTime = null;
  }

  /// 验证交易参数
  static Map<String, String> validateTransactionParams({
    required double amount,
    String? transactionId,
    int? timeout,
    int? maxStatusInfos,
  }) {
    Map<String, String> errors = {};
    if (amount <= 0) {
      errors['amount'] = '金额必须大于0';
    }
    if (amount > 999999.99) {
      errors['amount'] = '金额不能超过999999.99';
    }
    if (transactionId != null && transactionId.length > 50) {
      errors['transactionId'] = '交易ID长度不能超过50个字符';
    }
    if (timeout != null && (timeout < 10 || timeout > 300)) {
      errors['timeout'] = '超时时间必须在10-300秒之间';
    }
    if (maxStatusInfos != null && (maxStatusInfos < 1 || maxStatusInfos > 10)) {
      errors['maxStatusInfos'] = '最大状态信息数量必须在1-10之间';
    }
    return errors;
  }

  void setOperationTimeout(Duration timeout) {
    _operationTimeout = timeout;
  }

  void setConnectionTimeout(Duration timeout) {
    _connectionTimeout = timeout;
  }

  Map<String, dynamic> getConnectionInfo() {
    return {
      'ip': ip,
      'port': port,
      'isConnected': _isConnected,
      'hasSocket': socket != null,
    };
  }

  /// 将ISO-8859-2编码的字节转换为UTF-8字符串
  /// ISO-8859-2 (Latin-2) 用于中欧语言，包括捷克语、斯洛伐克语等
  String _decodeIso8859_2(List<int> bytes) {
    // ISO-8859-2到UTF-8的映射表（0x80-0xFF范围的特殊字符）
    // 0x00-0x7F: ASCII字符，直接使用
    // 0x80-0xFF: ISO-8859-2特殊字符，需要映射到UTF-8
    // 捷克语常用字符：
    //   小写: á(0xE1), é(0xE9), í(0xED), ó(0xF3), ú(0xFA), ý(0xFD)
    //         č(0xE8), ď(0xEF), ě(0xEC), ň(0xF2), ř(0xF8), š(0x9A), ť(0x9D), ž(0x9E)
    //   大写: Á(0xC1), É(0xC9), Í(0xCD), Ó(0xD3), Ú(0xDA), Ý(0xDD)
    //         Č(0xC8), Ď(0xCF), Ě(0xCC), Ň(0xD2), Ř(0xD8), Š(0x8A), Ť(0x8C), Ž(0x8E)
    final buffer = StringBuffer();
    for (int byte in bytes) {
      if (byte < 0x80) {
        // ASCII字符（0x00-0x7F），直接使用
        buffer.writeCharCode(byte);
      } else {
        // ISO-8859-2特殊字符（0x80-0xFF），从映射表查找
        final utf8Char = _iso8859_2ToUtf8[byte];
        if (utf8Char != null) {
          buffer.write(utf8Char);
        } else {
          // 如果不在映射表中（理论上不应该发生），使用Latin1解码作为后备
          try {
            buffer.writeCharCode(byte);
          } catch (e) {
            buffer.write('?');
          }
        }
      }
    }
    return buffer.toString();
  }

  /// ISO-8859-2到UTF-8字符映射表（0x80-0xFF）
  static const Map<int, String> _iso8859_2ToUtf8 = {
    // 0x80-0x9F: 控制字符和特殊字符
    0x80: '\u0080', // 控制字符
    0x81: '\u0081', // 控制字符
    0x82: '\u0082', // 控制字符
    0x83: '\u0083', // 控制字符
    0x84: '\u0084', // 控制字符
    0x85: '\u0085', // 控制字符
    0x86: '\u0086', // 控制字符
    0x87: '\u0087', // 控制字符
    0x88: '\u0088', // 控制字符
    0x89: '\u0089', // 控制字符
    0x8A: '\u0160', // Š (大写，捷克语)
    0x8B: '\u008B', // 控制字符
    0x8C: '\u0164', // Ť (大写，捷克语)
    0x8D: '\u0162', // Ţ
    0x8E: '\u017D', // Ž (大写，捷克语)
    0x8F: '\u008F', // 控制字符
    0x90: '\u0090', // 控制字符
    0x91: '\u2018', // '
    0x92: '\u2019', // '
    0x93: '\u201C', // "
    0x94: '\u201D', // "
    0x95: '\u2022', // •
    0x96: '\u2013', // –
    0x97: '\u2014', // —
    0x98: '\u0098', // 控制字符
    0x99: '\u2122', // ™
    0x9A: '\u0161', // š (小写，捷克语)
    0x9B: '\u203A', // ›
    0x9C: '\u015A', // Ś
    0x9D: '\u0165', // ť (小写，捷克语)
    0x9E: '\u017E', // ž (小写，捷克语)
    0x9F: '\u017A', // ź
    // 0xA0-0xBF: 特殊空格和标点
    0xA0: '\u00A0', // 不间断空格
    0xA1: '\u0104', // Ą
    0xA2: '\u02D8', // ˘
    0xA3: '\u0141', // Ł
    0xA4: '\u00A4', // ¤
    0xA5: '\u013D', // Ľ
    0xA6: '\u015A', // Ś
    0xA7: '\u00A7', // §
    0xA8: '\u0160', // Š
    0xA9: '\u015E', // Ş
    0xAA: '\u0164', // Ť
    0xAB: '\u0179', // Ź
    0xAC: '\u00AD', // 软连字符
    0xAD: '\u017D', // Ž
    0xAE: '\u017B', // Ż
    0xAF: '\u00AF', // ¯
    // 0xB0-0xBF
    0xB0: '\u0171', // ű
    0xB1: '\u0105', // ą
    0xB2: '\u02DB', // ˛
    0xB3: '\u0142', // ł
    0xB4: '\u0144', // ń
    0xB5: '\u013E', // ľ
    0xB6: '\u015B', // ś
    0xB7: '\u02C7', // ˇ
    0xB8: '\u0161', // š
    0xB9: '\u015F', // ş
    0xBA: '\u0165', // ť
    0xBB: '\u017A', // ź
    0xBC: '\u02DD', // ˝
    0xBD: '\u017E', // ž
    0xBE: '\u017C', // ż
    0xBF: '\u0154', // Ŕ
    // 0xC0-0xCF: 大写字母（捷克语）
    0xC0: '\u0102', // Ă
    0xC1: '\u00C1', // Á
    0xC2: '\u00C2', // Â
    0xC3: '\u0102', // Ă
    0xC4: '\u00C4', // Ä
    0xC5: '\u0139', // Ĺ
    0xC6: '\u0106', // Ć
    0xC7: '\u00C7', // Ç
    0xC8: '\u010C', // Č
    0xC9: '\u00C9', // É
    0xCA: '\u0118', // Ę
    0xCB: '\u00CB', // Ë
    0xCC: '\u011A', // Ě
    0xCD: '\u00CD', // Í
    0xCE: '\u00CE', // Î
    0xCF: '\u010E', // Ď
    // 0xD0-0xDF: 大写字母（捷克语）
    0xD0: '\u0110', // Đ
    0xD1: '\u0143', // Ń
    0xD2: '\u0147', // Ň
    0xD3: '\u00D3', // Ó
    0xD4: '\u00D4', // Ô
    0xD5: '\u0150', // Ő
    0xD6: '\u00D6', // Ö
    0xD7: '\u00D7', // ×
    0xD8: '\u0158', // Ř
    0xD9: '\u016E', // Ů
    0xDA: '\u00DA', // Ú
    0xDB: '\u0170', // Ű
    0xDC: '\u00DC', // Ü
    0xDD: '\u00DD', // Ý
    0xDE: '\u0162', // Ţ
    0xDF: '\u00DF', // ß
    // 0xE0-0xEF: 小写字母（捷克语）
    0xE0: '\u0155', // ŕ
    0xE1: '\u00E1', // á
    0xE2: '\u00E2', // â
    0xE3: '\u0103', // ă
    0xE4: '\u00E4', // ä
    0xE5: '\u013A', // ĺ
    0xE6: '\u0107', // ć
    0xE7: '\u00E7', // ç
    0xE8: '\u010D', // č
    0xE9: '\u00E9', // é
    0xEA: '\u0119', // ę
    0xEB: '\u00EB', // ë
    0xEC: '\u011B', // ě
    0xED: '\u00ED', // í
    0xEE: '\u00EE', // î
    0xEF: '\u010F', // ď
    // 0xF0-0xFF: 小写字母（捷克语）
    0xF0: '\u0111', // đ
    0xF1: '\u0144', // ń
    0xF2: '\u0148', // ň
    0xF3: '\u00F3', // ó
    0xF4: '\u00F4', // ô
    0xF5: '\u0151', // ő
    0xF6: '\u00F6', // ö
    0xF7: '\u00F7', // ÷
    0xF8: '\u0159', // ř
    0xF9: '\u016F', // ů
    0xFA: '\u00FA', // ú
    0xFB: '\u0171', // ű
    0xFC: '\u00FC', // ü
    0xFD: '\u00FD', // ý
    0xFE: '\u0163', // ţ
    0xFF: '\u02D9', // ˙
  };
}
